#常用编译选项、引用库、命令等在此统一定义
#引入本文件前需要设置：BASEDIR、TARGET、SOURCE
#BASEDIR是代码根目录
#TARGET是生成的文件名
#SOURCE是代码源文件的类型，默认是c
COMPILE_DEBUG = 1
CXX := gcc

ifeq ($(SOURCE),)
SOURCE := c
endif

ifeq ($(COMPILE_DEBUG), 1)
CXXFLAGS += -std=c99 -Wall -O0 -g -fPIC
else 
CXXFLAGS += -std=c99 -Wall -O2 -fPIC
endif

LDFLAGS += 

DEFINES += 

INCLUDE :=

LIBRARY +=

SOURCE_PATH := $(shell pwd)
BUILD_PATH := build

SOURCES := $(patsubst ./%.$(SOURCE), %.$(SOURCE), $(foreach dir, $(shell find -maxdepth 3 -type d), $(wildcard $(dir)/*.$(SOURCE))))
OBJECTS := $(patsubst %.$(SOURCE), $(BUILD_PATH)/%.o, $(SOURCES))
DEPENDS := $(patsubst %.o, %.d, %(OBJECTS))

TARGER_OBJECTS := $(filter-out %unittest.o %benchmark.o, $(OBJECTS))
UNITTEST_OBJECTS := $(filter-out %main.o %benchmark.o, $(OBJECTS))
BENCHMARK_OBJECTS := $(filter-out %main.o %unittest.o, $(OBJECTS))

TARGET_UNITTEST := $(subst .so,, $(subst .a,, $(TARGET)))_unittest
TARGET_BENCHMARK := $(subst .so,,$(subst .a,,$(TARGET)))_benchmark

targer : $(TARGET)
unittest : $(TARGET_UNITTEST)
benchmark : $(TARGET_BENCHMARK)

$(TARGET) : $(TARGER_OBJECTS)
ifneq ($(findstring .a, $@), )
	ar crv $@ $^
else 
ifneq ($(findstring .so, $(TARGET)), )
	$(CXX) $(CXXFLAGS) -shared $^ $(LIBRARY) $(LDFLAGS) -o $@
else
	$(CXX) $(CXXFLAGS) $^ $(LIBRARY) $(LDFLAGS) -o $@
endif
endif

$(TARGET_UNITTEST) : $(UNITTEST_OBJECTS)
	$(CXX) $(CXXFLAGS) $(LIBRARY) $^ $(LDFLAGS) -o $@
$(TARGET_BENCHMARK) : $(BENCHMARK_OBJECTS)
	$(CXX) $(CXXFLAGS) $(LIBRARY) $^ $(LDFLAGS) -o $@

$(BUILD_PATH)/%.o : $(SOURCE_PATH)/%.$(SOURCE)
	mkdir -p $(dir $(OBJECTS))
	$(CXX) $(INCLUDE) $(CXXFLAGS) -MM -MT $@ -MF $(patsubst %.o, %.d, $@) $<
	$(CXX) $(DEFINES) $(INCLUDE) $(CXXFLAGS) -o $@ -c $<


clean :
	rm -f $(TARGET) $(TARGET_UNITTEST) $(TARGET_BENCHMARK)
	rm -f $(OBJECTS) *.o *.d
	rm -rf $(BUILD_PATH)

test :
	echo $(CXXFLAGS)